{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Семинар 5. Шаблоны"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Специфика компиляции шаблонов"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```c++\n",
    "#include <iostream>\n",
    "#include <string>\n",
    "\n",
    "template<typename T, int n>\n",
    "class PlainArray {\n",
    "public:\n",
    "    PlainArray() = default;\n",
    "    \n",
    "    T& operator[](size_t index) {\n",
    "        return arr_[index];\n",
    "    }\n",
    "    \n",
    "    const T& operator[](size_t index) const {\n",
    "        return arr_[index];\n",
    "    }\n",
    "\n",
    "    void clear_first() {\n",
    "        arr_[0].clear();\n",
    "    }\n",
    "\n",
    "private:\n",
    "    T arr_[n];\n",
    "};\n",
    "\n",
    "int main(int argc, char** argv) {\n",
    "    PlainArray<int, 10> pai;\n",
    "    pai[5] = 42;\n",
    "    std::cout << pai[5] << std::endl;\n",
    "\n",
    "    PlainArray<std::string, 3> pas;\n",
    "    pas[0] = \"run, Forest, run!\";\n",
    "    std::cout << pas[0] << std::endl;\n",
    "\n",
    "    pas.clear_first();\n",
    "    // # pai.clear_first();\n",
    "    return 0;\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Примеры шаблонных функций / классов из стандартной библиотеки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Рассмотреть примеры подробнее, специализации (если есть). Показать секции member types, non-member functions etc."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://en.cppreference.com/w/cpp/numeric/gcd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://en.cppreference.com/w/cpp/algorithm/max_element"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://en.cppreference.com/w/cpp/numeric/complex"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://en.cppreference.com/w/cpp/string/basic_string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://en.cppreference.com/w/cpp/container/vector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Member types"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```c++\n",
    "#include <iostream>\n",
    "#include <string>\n",
    "#include <vector>\n",
    "\n",
    "template<typename T>\n",
    "class Stack {\n",
    "public:\n",
    "    using container = std::vector<T>;\n",
    "    using value_type = T;\n",
    "\n",
    "    void push(const T& x) {\n",
    "        v_.push_back(x);\n",
    "    }\n",
    "\n",
    "    T pop() {\n",
    "        T rv = v_.back();\n",
    "        v_.pop_back();\n",
    "        return rv;\n",
    "    }\n",
    "\n",
    "public:\n",
    "    class iterator { ... };\n",
    "\n",
    "    class const_iterator { ... };\n",
    "\n",
    "    iterator begin() { return ...; }\n",
    "    iterator end() { return ...; }\n",
    "    const_iterator begin() const { return ...; }\n",
    "    const_iterator end() const { return ...; }\n",
    "\n",
    "private:\n",
    "    container v_;\n",
    "};\n",
    "\n",
    "int main(int argc, char **argv)  {\n",
    "    Stack<int>::container cont{1, 2, 3, 4, 5};\n",
    "    Stack<int>::container::value_type some_value = 42;\n",
    "\n",
    "    Stack<int> s;\n",
    "    Stack<int>::iterator s_begin = s.begin();\n",
    "    Stack<int>::iterator s_end = s.end();\n",
    "\n",
    "    for (int x : s)\n",
    "        std::cout << x << std::endl;\n",
    "    \n",
    "    for (Stack<int>::value_type x : s)\n",
    "        std::cout << x << std::endl;\n",
    "\n",
    "    return 0;\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Упражнение:__\n",
    "* N-мерный вектор + стандартные операции над ним + length + distance + dot + сумма векторов и т.п."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
